﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using Grafic;
using System.Windows.Forms;
using System.Threading;

namespace ParseData
{
    /// <summary>
    /// Console application for reading the sensors datas.
    /// </summary>
    public class TestReader
    {
        private TcpClient tcpclnt;
        public bool stop = false;

        // list of attached sensors.
        private static List<ISensor> sensors = new List<ISensor>();

        // getters & setters for grafic...
        private static GraficTemperatura _gtemp = null;
        private static GraficTemperatura gtemp
        {
            get
            {
                while (_gtemp == null) Thread.Sleep(100);
                return _gtemp;
            }
            set
            {
                _gtemp = value;
            }
        }
        private static GraficLumina _gLum = null;
        private static GraficLumina gLum
        {
            get
            {
                while (_gLum == null) Thread.Sleep(100);
                return _gLum;
            }
            set
            {
                _gLum = value;
            }
        }
        private static GraficBP _gbp = null;
        private static GraficBP gbp
        {
            get
            {
                while (_gbp == null) Thread.Sleep(100);
                return _gbp;
            }
            set
            {
                _gbp = value;
            }
        }
        private static GraficECG _gecg;
        private static GraficECG gecg
        {
            get
            {
                while (_gecg == null) Thread.Sleep(100);
                return _gecg;
            }
            set
            {
                _gecg = value;
            }
        }

        private string ip;
        private string port;
        private string limba;

        public DateTime dataInceput;
        public DateTime dataSfarsit;
        public bool dataSetata;

        public static string CNP;

        public TestReader(string ip, string port, string limba)
        {
            this.ip = ip;
            this.port = port;
            this.limba = limba;
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public void readData()
        {
            // open server connection
            tcpclnt = new TcpClient();

            try
            {
                Console.WriteLine("Connecting.....");
                tcpclnt.Connect(ip,Int32.Parse(port));
                Console.WriteLine("Connected");

                // Now send the user CNP
                ASCIIEncoding asen = new ASCIIEncoding();
                Stream stm = tcpclnt.GetStream();

                byte[] buff = new byte[4096], tmp;
                string str = CNP;

                // lungime
                int len = asen.GetBytes(str).Length;
                tmp = BitConverter.GetBytes(len);
                for (int i = 0; i < 4; i++)
                    buff[i] = tmp[i];

                // id
                tmp = BitConverter.GetBytes(12);
                for (int i = 0; i < 4; i++)
                    buff[4 + i] = tmp[i];

                // data
                tmp = asen.GetBytes(str);
                for (int i = 0; i < len; i++)
                    buff[8 + i] = tmp[i];

                // transmitere
                stm.Write(buff, 0, 8 + len);
            }
            catch (System.Net.Sockets.SocketException ex)
            {
                Console.WriteLine("Connection failed! Just displaying the information." + ex);
                tcpclnt = null;
                ShowErrorMsg("ErrorConectareServer");
            }

            // displaying sensors values.
            bool hasValues = true;
            while (hasValues)
            {
                if (stop == true)
                {
                    break;
                }
                int nConnectedSensors = 0;
                foreach (ISensor s in sensors)
                {
                    if (stop == true)
                    {
                        break;
                    }
                    ISensorReading reading = s.ReadNewValue();
                    if (reading != null)
                    {
                        nConnectedSensors++;

                        Console.WriteLine("Senzor:{0} ({1}): {2}", s.SenzorID, s.TypeName, reading.ReadableString);

                        if (s.TypeName.Contains("temperature senzor"))
                        {
                            if (dataSetata == false)
                            {
                                dataInceput = DateTime.Parse(reading.ReadableString.Substring(5));
                                dataSetata = true;
                            }
                            dataSfarsit = DateTime.Parse(reading.ReadableString.Substring(5));
                            gtemp.AddValue(reading.ReadableString.Substring(0, 4), reading.ReadableString.Substring(5));
                        }
                        if (s.TypeName.Contains("light sensor"))
                        {
                            if (dataSetata == false)
                            {
                                dataInceput = DateTime.Parse(reading.ReadableString.Substring(5));
                                dataSetata = true;
                            }
                            dataSfarsit = DateTime.Parse(reading.ReadableString.Substring(5));
                            gLum.AddValue(reading.ReadableString.Substring(0, 4), reading.ReadableString.Substring(5));
                        }
                        if (s.TypeName.Contains("BP sensor"))
                        {
                            if (dataSetata == false)
                            {
                                dataInceput = DateTime.Parse(reading.ReadableString.Substring(11));
                                dataSetata = true;
                            }
                            dataSfarsit = DateTime.Parse(reading.ReadableString.Substring(11));
                            gbp.AddValue1(reading.ReadableString.Substring(0, 5), reading.ReadableString.Substring(11));
                            gbp.AddValue2(reading.ReadableString.Substring(6, 4), reading.ReadableString.Substring(11));
                        }
                        if (s.TypeName.Contains("ECG sensor"))
                        {
                            if (dataSetata == false)
                            {
                                dataInceput = DateTime.Parse(reading.ReadableString.Substring(11));
                                dataSetata = true;
                            }
                            dataSfarsit = DateTime.Parse(reading.ReadableString.Substring(11));
                            gecg.AddValue1(reading.ReadableString.Substring(0, 5), reading.ReadableString.Substring(11));
                            gecg.AddValue2(reading.ReadableString.Substring(5, 5), reading.ReadableString.Substring(11));
                        }
                        
                        // Sending data...
                        if (tcpclnt != null)
                            SendData(s.SenzorID, s.TypeName, reading.ReadableString);

                        ISensorReading average = s.AverageValue;
                        ISensorReading minimum = s.MinValue;
                        ISensorReading maximum = s.MaxValue;
                        Console.WriteLine("Senzor: {0} ({1}) average: {2}",
                            s.SenzorID,
                            s.TypeName,
                            average != null ? average.ReadableString : "none");
                        Console.WriteLine("Senzor: {0} ({1}) minimum: {2}",
                            s.SenzorID,
                            s.TypeName,
                            minimum != null ? minimum.ReadableString : "none");
                        Console.WriteLine("Senzor: {0} ({1}) maximum: {2}",
                            s.SenzorID,
                            s.TypeName,
                            maximum != null ? maximum.ReadableString : "none");

                        // displaying sensors minimum and maximumvalues.
                        if (minimum != null && minimum.HasValue())
                        {
                            Console.WriteLine();
                            Console.WriteLine("Nume sensor: " + s.TypeName + " Valoarea minima: " + minimum.ReadableString);
                            Console.WriteLine();
                        }
                        if (maximum != null && maximum.HasValue())
                        {
                            Console.WriteLine();
                            Console.WriteLine("Nume sensor: " + s.TypeName + " Valoarea maxima: " + maximum.ReadableString);
                            Console.WriteLine();
                        }

                        // reset sensors minimum and maximumvalues.
                        if (minimum != null)
                            s.ResetMinValue();
                        if (maximum != null)
                            s.ResetMaxValue();

                    }
                }

                // Diplay's the dates at 2 sec
                hasValues = nConnectedSensors > 0;
                DateTime time = DateTime.Now;              
                System.Threading.Thread.Sleep(2000);
                Console.WriteLine(time.ToString());
            }

            // Close connection
            if (tcpclnt != null)
                tcpclnt.Close();
        }

        private void SendData(string id, string type, string str)
        {
            try
            {
                ASCIIEncoding asen = new ASCIIEncoding();

                Stream stm = tcpclnt.GetStream();
                byte[] buff = new byte[4096], tmp;

                // lungime
                int len = asen.GetBytes(str).Length;
                tmp = BitConverter.GetBytes(len);
                for (int i = 0; i < 4; i++)
                    buff[i] = tmp[i];

                // id
                tmp = BitConverter.GetBytes(Int32.Parse(id));
                for (int i = 0; i < 4; i++)
                    buff[4 + i] = tmp[i];

                // data
                tmp = asen.GetBytes(str);
                for (int i = 0; i < len; i++)
                    buff[8 + i] = tmp[i];

                // transmitere
                stm.Write(buff, 0, 8 + len); 
            }
            catch
            {
                // Close connection
                tcpclnt.Close();
            }
        }

        /// <summary>Adding and displaing sensors.</summary>
        public static void addSensor(ISensor s)
        {
            sensors.Add(s);
            Console.WriteLine("ID " + s.SenzorID + " Nume -> " + s.TypeName);
            Console.WriteLine();
        }

        public static void removeAllSensors()
        {
            sensors.Clear();
        }

        public static void addGraficTemperatura(string CNP, string Nume, string Prenume,string limba)
        {
            gtemp = new GraficTemperatura(CNP, Nume, Prenume, limba);
            gtemp.dataInceput = DateTime.Now;
            gtemp.CreateGraph();
        
        }
        public static void displayGraficTemperatura()
        {
            gtemp.Visible = true;
            gtemp.Show();

        }

        public static void addGraficLumina(string CNP, string Nume, string Prenume, string limba)
        {
            gLum = new GraficLumina(CNP, Nume, Prenume, limba);
            gLum.dataInceput = DateTime.Now;
            gLum.CreateGraph();

        }
        public static void displayGraficLumina()
        {
            gLum.Visible = true;
            gLum.Show();

        }

        public static void addGraficBP(string CNP, string Nume, string Prenume, string limba)
        {
            gbp = new GraficBP(CNP, Nume, Prenume, limba);
            gbp.dataInceput1 = DateTime.Now;
            gbp.dataInceput2 = DateTime.Now;
            gbp.CreateGraph1();
            gbp.CreateGraph2();

        }

        public static void displayGraficBP()
        {
            gbp.Visible = true;
            gbp.Show();

        }

        public static void addGraficECG(string CNP, string Nume, string Prenume, string limba)
        {
            gecg = new GraficECG(CNP, Nume, Prenume, limba);
            gecg.dataInceput1 = DateTime.Now;
            gecg.dataInceput2 = DateTime.Now;
            gecg.CreateGraph1();
            gecg.CreateGraph2();

        }

        public static void displayGraficECG()
        {
            gecg.Visible = true;
            gecg.Show();

        }

        private void ShowErrorMsg(string msgID)
        {
            XMLParser parser = new XMLParser(@"C:\Language" + limba + ".xml");

            Dictionary<string, string> dict =
                parser.ExtractAttributePairs("MesajeEroare", string.Empty, string.Empty, "name", "formula");

            MessageBox.Show(dict[msgID] + ip,
                            dict["TitluEroare"],
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
        }
    }
}
